{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "%load_ext autoreload\n",
    "%autoreload 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Data folder is /media/luca/DATA/DATASETS\n",
      "Experiment save directory is  /media/luca/DATA/EXPERIMENTS\n"
     ]
    }
   ],
   "source": [
    "import tensorflow as tf\n",
    "import numpy as np\n",
    "import experiment_manager as em\n",
    "import far_ho as far"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "4\n"
     ]
    }
   ],
   "source": [
    "far.utils._check()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "try: ss.close()\n",
    "except: pass\n",
    "tf.reset_default_graph()\n",
    "ss = tf.InteractiveSession()\n",
    "v1 = tf.Variable([1.,3])\n",
    "\n",
    "v2 = tf.Variable([[-1., -2], [1., 0.]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "lmbd = far.get_hyperparameter('lambda', \n",
    "                              initializer=tf.zeros_initializer,\n",
    "                             shape=v2.get_shape())\n",
    "\n",
    "cost = tf.reduce_mean(v1**2) + tf.reduce_sum(lmbd*v2**2)\n",
    "\n",
    "io_optim = far.MomentumOptimizer(far.get_hyperparameter('eta', 0.1), \n",
    "                                   far.get_hyperparameter('mu', .9))\n",
    "\n",
    "io_optim_dict = io_optim.minimize(cost) \n",
    "\n",
    "oo = tf.reduce_mean(v1*v2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "rhg = far.ReverseHg()\n",
    "rhg.compute_gradients(oo, io_optim_dict)\n",
    "\n",
    "optim_oo = tf.train.AdamOptimizer(.01)\n",
    "ts_hy = optim_oo.apply_gradients(rhg.hgrads_hvars())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<tf.Variable 'Variable:0' shape=(2,) dtype=float32_ref>,\n",
       " <tf.Variable 'Variable_1:0' shape=(2, 2) dtype=float32_ref>,\n",
       " <tf.Variable 'lambda:0' shape=(2, 2) dtype=float32_ref>,\n",
       " <tf.Variable 'eta:0' shape=() dtype=float32_ref>,\n",
       " <tf.Variable 'mu:0' shape=() dtype=float32_ref>,\n",
       " <tf.Variable 'Variable/Momentum:0' shape=(2,) dtype=float32_ref>,\n",
       " <tf.Variable 'Variable_1/Momentum:0' shape=(2, 2) dtype=float32_ref>,\n",
       " <tf.Variable 'beta1_power:0' shape=() dtype=float32_ref>,\n",
       " <tf.Variable 'beta2_power:0' shape=() dtype=float32_ref>,\n",
       " <tf.Variable 'lambda/Adam:0' shape=(2, 2) dtype=float32_ref>,\n",
       " <tf.Variable 'lambda/Adam_1:0' shape=(2, 2) dtype=float32_ref>,\n",
       " <tf.Variable 'eta/Adam:0' shape=() dtype=float32_ref>,\n",
       " <tf.Variable 'eta/Adam_1:0' shape=() dtype=float32_ref>,\n",
       " <tf.Variable 'mu/Adam:0' shape=() dtype=float32_ref>,\n",
       " <tf.Variable 'mu/Adam_1:0' shape=() dtype=float32_ref>]"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tf.global_variables()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<tf.Variable 'lambda:0' shape=(2, 2) dtype=float32_ref>,\n",
       " <tf.Variable 'eta:0' shape=() dtype=float32_ref>,\n",
       " <tf.Variable 'mu:0' shape=() dtype=float32_ref>]"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "far.utils.hyperparameters()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[array([[ 0.,  0.],\n",
       "        [ 0.,  0.]], dtype=float32), 0.1, 0.89999998]"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tf.global_variables_initializer().run()\n",
    "ss.run(far.utils.hyperparameters())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "rhg.run(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[array([[-1.21823609, -7.30941772],\n",
       "        [ 1.21823609,  0.        ]], dtype=float32), -1.2315257, 4.794621]"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ss.run(far.utils.hypergradients())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# ss.run(ts_hy)  # perform an hypergradient descent step....\n",
    "# print(ss.run(far.utils.hyperparameters()))\n",
    "# print(ss.run(oo))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# check with rfho"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Environment variable RFHO_EXP_FOLDER not found. Current directory will be used\n",
      "Experiment save directory is  /media/luca/DATA/Progs/FAR-HO/tests/Experiments\n",
      "Environment variable RFHO_DATA_FOLDER not found. Variables HELP_WIN and HELP_UBUNTU contain info.\n",
      "Data folder is /media/luca/DATA/Progs/FAR-HO/tests\n"
     ]
    }
   ],
   "source": [
    "import rfho as rf"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Warning: creating nodes at tf.Session runtime: node Tensor(\"vectorization:0\", shape=(6,), dtype=float32)\n",
      "Warning: creating nodes at tf.Session runtime: node Tensor(\"augmented_variables/0/vectorization:0\", shape=(6,), dtype=float32)\n",
      "Warning: creating nodes at tf.Session runtime: node Tensor(\"vectorization_1:0\", shape=(12,), dtype=float32)\n",
      "Warning: creating nodes at tf.Session runtime: node Tensor(\"Reshape_4:0\", shape=(2, 2), dtype=float32)\n",
      "Warning: creating nodes at tf.Session runtime: node Tensor(\"Reshape_5:0\", shape=(2,), dtype=float32)\n",
      "Warning: creating nodes at tf.Session runtime: node Tensor(\"Reshape_6:0\", shape=(2,), dtype=float32)\n",
      "Warning: creating nodes at tf.Session runtime: node Tensor(\"Reshape_7:0\", shape=(2, 2), dtype=float32)\n"
     ]
    }
   ],
   "source": [
    "w, c, co = rf.vectorize_model([v1, v2], cost, oo, augment=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Warning: creating nodes at tf.Session runtime: node Tensor(\"Momentum_1/Reshape:0\", shape=(2, 2), dtype=float32)\n",
      "Warning: creating nodes at tf.Session runtime: node Tensor(\"Momentum_1/Assign:0\", shape=(2, 2), dtype=float32_ref)\n",
      "Warning: creating nodes at tf.Session runtime: node Tensor(\"Momentum_1/Reshape_1:0\", shape=(2,), dtype=float32)\n",
      "Warning: creating nodes at tf.Session runtime: node Tensor(\"Momentum_1/Assign_1:0\", shape=(2,), dtype=float32_ref)\n",
      "Warning: creating nodes at tf.Session runtime: node Tensor(\"Momentum_1/Reshape_2:0\", shape=(2,), dtype=float32)\n",
      "Warning: creating nodes at tf.Session runtime: node Tensor(\"Momentum_1/Assign_2:0\", shape=(2,), dtype=float32_ref)\n",
      "Warning: creating nodes at tf.Session runtime: node Tensor(\"Momentum_1/Reshape_3:0\", shape=(2, 2), dtype=float32)\n",
      "Warning: creating nodes at tf.Session runtime: node Tensor(\"Momentum_1/Assign_3:0\", shape=(2, 2), dtype=float32_ref)\n"
     ]
    }
   ],
   "source": [
    "dyn = rf.MomentumOptimizer.create(w, 0.1, 0.9, loss=c)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Warning: creating nodes at tf.Session runtime: node Tensor(\"w_history_ops/Reshape:0\", shape=(2, 2), dtype=float32)\n",
      "Warning: creating nodes at tf.Session runtime: node Tensor(\"w_history_ops/Assign:0\", shape=(2, 2), dtype=float32_ref)\n",
      "Warning: creating nodes at tf.Session runtime: node Tensor(\"w_history_ops/Reshape_1:0\", shape=(2,), dtype=float32)\n",
      "Warning: creating nodes at tf.Session runtime: node Tensor(\"w_history_ops/Assign_1:0\", shape=(2,), dtype=float32_ref)\n",
      "Warning: creating nodes at tf.Session runtime: node Tensor(\"w_history_ops/Reshape_2:0\", shape=(2,), dtype=float32)\n",
      "Warning: creating nodes at tf.Session runtime: node Tensor(\"w_history_ops/Assign_2:0\", shape=(2,), dtype=float32_ref)\n",
      "Warning: creating nodes at tf.Session runtime: node Tensor(\"w_history_ops/Reshape_3:0\", shape=(2, 2), dtype=float32)\n",
      "Warning: creating nodes at tf.Session runtime: node Tensor(\"w_history_ops/Assign_3:0\", shape=(2, 2), dtype=float32_ref)\n"
     ]
    }
   ],
   "source": [
    "hyperg = rf.HyperOptimizer(dyn, {co: lmbd}, rf.ReverseHG)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "hyperg.initialize()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "hgs = hyperg.run(10, val_feed_dict_suppliers={co:lambda: None},\n",
    "                 _debug_no_hyper_update=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "rfho\n",
      "[array([[-1.21823609, -7.30941725],\n",
      "       [ 1.21823609,  0.        ]], dtype=float32)]\n",
      "far\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[array([[-1.21823609, -7.30941772],\n",
       "        [ 1.21823609,  0.        ]], dtype=float32), -1.2315257, 4.794621]"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print('rfho')\n",
    "print(ss.run(hyperg.hyper_gradients.hyper_gradient_vars))\n",
    "print('far')\n",
    "ss.run(far.utils.hypergradients())  # there are also other hyperparameters"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# END... RESULTS ARE (almost the) SAME"
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python [conda root]",
   "language": "python",
   "name": "conda-root-py"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
